import 'dart:async';
import 'dart:math';
import 'dart:typed_data';

import 'package:flutter/material.dart';

import '../gallery_frame_animation_painter.dart';
import '../utils/image_util.dart';

class GalleryDetailPage extends StatefulWidget {
  const GalleryDetailPage({super.key});

  @override
  State<GalleryDetailPage> createState() => _GalleryDetailPageState();
}

class Mapping {
  double x;
  double y;
  int address;

  Mapping(this.x, this.y, this.address);
}

class LightPoint {
  double x;
  double y;
  Color color;
  int index;

  LightPoint(this.index, this.x, this.y, this.color);
}

class _GalleryDetailPageState extends State<GalleryDetailPage> {
  List<List<LightPoint>>? frames;
  int currentFrame = 0;
  Timer? timer;
  int frameDuration = 50;

  @override
  void initState() {
    List<Mapping> mappingList = List.generate(
        60000,
        (index) => Mapping(
            Random().nextDouble() * 799, Random().nextDouble() * 799, index));
    List<String> imageUrlList = List.generate(
        29,
        (index) =>
            'assets/images/animation1_${index.toString().padLeft(5, '0')}.png');

    _loadFrames(imageUrlList, mappingList).then((list) {
      setState(() {
        frames = list;
      });
      startTimerFrames();
    });

    super.initState();
  }

  Future<List<List<LightPoint>>> _loadFrames(
      List<String> imageUrlList, List<Mapping> mappingList) async {
    List<List<LightPoint>> list = [];

    for (int i = 0; i < imageUrlList.length; i++) {
      final imageUrl = imageUrlList[i];
      final image = await ImageUtil.getUIImage(imageUrl);
      final imageWidth = image.width;
      final byteData = await image.toByteData();

      final imageData = Uint8List.view(byteData!.buffer);
      List<LightPoint> frame = [];
      for (int j = 0; j < mappingList.length; j++) {
        Mapping mapping = mappingList[j];
        int pixelPosition =
            (mapping.y.round() * imageWidth * 4) + mapping.x.round() * 4;
        int alpha = imageData[pixelPosition + 3];
        Color color = Color.fromARGB(
          alpha,
          imageData[pixelPosition],
          imageData[pixelPosition + 1],
          imageData[pixelPosition + 2],
        );
        frame.add(LightPoint(mapping.address, mapping.x, mapping.y, color));
      }
      list.add(frame);
    }

    return list;
  }

  void startTimerFrames() {
    if (frames?.isNotEmpty ?? false) {
      if (frames!.length > 1) {
        timer = Timer.periodic(Duration(milliseconds: frameDuration), (timer) {
          if (!mounted) {
            timer.cancel();
            return;
          }
          setState(() {
            currentFrame++;
            if (currentFrame > frames!.length - 1) {
              currentFrame = 0;
            }
          });
        });
      } else {
        setState(() {
          currentFrame = 0;
        });
      }
    }
  }

  @override
  void dispose() {
    timer?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: frames != null
            ? CustomPaint(
                painter: GalleryFrameAnimationPainter(
                  800,
                  800,
                  frames![currentFrame],
                ),
                child: Container(),
              )
            : const Center(child: CircularProgressIndicator()));
  }
}
